if(!require("plotly")) {install.packages("plotly")}
Loading required package: plotly
Loading required package: ggplot2
Find out what's changed in ggplot2 at https://github.com/tidyverse/ggplot2/releases.

Attaching package: ‘plotly’

The following object is masked from ‘package:ggplot2’:

    last_plot

The following object is masked from ‘package:stats’:

    filter

The following object is masked from ‘package:graphics’:

    layout
# install.packages("latex2exp")
# install.packages("BiocManager") 
# install.packages("corrplot")
# BiocManager::install("EBImage")

if(!require("lme4")){install.packages("lme4")}
Loading required package: lme4
Loading required package: Matrix
if(!require("lmerTest")){install.packages("lmerTest")}
Loading required package: lmerTest

Attaching package: ‘lmerTest’

The following object is masked from ‘package:lme4’:

    lmer

The following object is masked from ‘package:stats’:

    step
if(!require("nlme")){install.packages("nlme")}
Loading required package: nlme

Attaching package: ‘nlme’

The following object is masked from ‘package:lme4’:

    lmList
if(!require("formattable")){install.packages("formattable")}
Loading required package: formattable

Attaching package: ‘formattable’

The following object is masked from ‘package:plotly’:

    style
if(!require("xgboost")){install.packages("xgboost")}
Loading required package: xgboost

Attaching package: ‘xgboost’

The following object is masked from ‘package:plotly’:

    slice
if(!require("processx")) {install.packages("processx")}
Loading required package: processx
if(!require("mefa")){install.packages("mefa")}
Loading required package: mefa
mefa 3.2-7   2016-01-11
library(plotly)
library(lme4)
library(lmerTest)
library(nlme)
library(formattable)
library(xgboost)

### Load libraries
library(EBImage)

Attaching package: ‘EBImage’

The following object is masked from ‘package:plotly’:

    toRGB
library(ggplot2)
library(stringr)
library(gridExtra)

Attaching package: ‘gridExtra’

The following object is masked from ‘package:EBImage’:

    combine
library(latex2exp)

Attaching package: ‘latex2exp’

The following object is masked from ‘package:plotly’:

    TeX
packageVersion('plotly')
[1] ‘4.9.1’
Sys.setenv("plotly_username"="thuynh32")
Sys.setenv("plotly_api_key"="xcSv1yzujDc1IGEwQlr2")
drive1 <- read.csv('../../../data/TT1/preprocessed/Analysis/TT1_Drive_1_PP.csv')
drive2 <- read.csv('../../../data/TT1/preprocessed/Analysis/TT1_Drive_2_PP.csv')
drive3 <- read.csv('../../../data/TT1/preprocessed/Analysis/TT1_Drive_3_PP.csv')
drive4 <- read.csv('../../../data/TT1/preprocessed/Analysis/TT1_Drive_4_PP.csv', stringsAsFactors = T)
combinedDf <- cbind(drive4, 
                    drive2$MeanPP_SegMax, drive3$MeanPP_SegMax, 
                    drive1$MeanPP_Seg0, drive2$MeanPP_Seg0, drive3$MeanPP_Seg0,
                    drive2$StdPP, drive3$StdPP 
                  )
names(combinedDf) <- c(names(drive4), "PP_Dev_2_Straight", "PP_Dev_3_Straight", "PP_Dev_1_Turning", "PP_Dev_2_Turning", "PP_Dev_3_Turning", "Std_PP_2", "Std_PP_3")

combinedDf$Subject <- paste0("#", str_pad(combinedDf$Subject, 2, pad="0"))
combinedDf_NoStressor <- combinedDf[combinedDf$Activity == "NO",]
combinedDf_Cognitive <- combinedDf[combinedDf$Activity == "C",]
combinedDf_Motoric <- combinedDf[combinedDf$Activity == "M",]

combinedDf_NoStressor$Subject <- as.factor(combinedDf_NoStressor$Subject)
combinedDf_Cognitive$Subject <- as.factor(combinedDf_Cognitive$Subject)
combinedDf_Motoric$Subject <- as.factor(combinedDf_Motoric$Subject)
COLOR_NORMAL <- list(color='rgb(120,120,120)')
COLOR_COGNITIVE <- list(color='rgb(158,202,225)')
COLOR_MOTORIC <- list(color='rgb(58,200,225)')
COLOR_FAILURE <- list(color='red')

yAxis <- list(
  title = 'Perinasal Perspiration (Log)',
  range=c(-0.3, 0.5)
)

THRESHOLD_MILD = 0.07
THRESHOLD_EXTREME = 0.2

MARKER_LINE_MILD = list(color="blue")
MARKER_LINE_EXTREME = list(color="red")
fig_NoStressor <- plot_ly(combinedDf_NoStressor, x = ~Subject, y = ~PP_Dev_2_Straight, type = 'bar', name = 'Cognitive - Mean PP (Straight)', marker=COLOR_COGNITIVE) %>%
  add_trace(y = ~PP_Dev_3_Straight, name = 'Motoric - Mean PP (Straight)', marker=COLOR_MOTORIC) %>% 
  add_trace(y = ~PP_Dev_2_Turning, name = 'Cognitive - Mean PP (Turning)', marker=COLOR_COGNITIVE) %>% 
  add_trace(y = ~PP_Dev_3_Turning, name = 'Motoric - Mean PP (Turning)', marker=COLOR_MOTORIC) %>% 
  add_trace(y = ~PP_Dev, name = 'Failure - PP Deviation', marker=COLOR_FAILURE) %>% 
  add_segments(x="#01", xend="#41", y = THRESHOLD_MILD, yend = THRESHOLD_MILD, name="Threshold: Mild Change of PP",
                           line=list(color="blue", dash = 'dot')) %>%
  # add_segments(x="#01", xend="#41", y = THRESHOLD_EXTREME, yend = THRESHOLD_EXTREME, name="Threshold: Extreme Change of PP",
  #                          line=list(color="darkred", dash = 'dot')) %>%
  layout(yaxis = yAxis, barmode = 'group', title="Failure Driving \n Group=No Stressor")

htmltools::tagList(fig_NoStressor)
A marker object has been specified, but markers is not in the mode
Adding markers to the mode...
A marker object has been specified, but markers is not in the mode
Adding markers to the mode...
fig_Cognitive <- plot_ly(combinedDf_Cognitive, x = ~Subject, y = ~PP_Dev_2_Straight, type = 'bar', name = 'Cognitive - Mean PP (Straight)', marker=COLOR_COGNITIVE) %>%
  add_trace(y = ~PP_Dev_3_Straight, name = 'Motoric - Mean PP (Straight)', marker=COLOR_MOTORIC) %>% 
  add_trace(y = ~PP_Dev_2_Turning, name = 'Cognitive - Mean PP (Turning)', marker=COLOR_COGNITIVE) %>% 
  add_trace(y = ~PP_Dev_3_Turning, name = 'Motoric - Mean PP (Turning)', marker=COLOR_MOTORIC) %>% 
  add_trace(y = ~PP_Dev, name = 'Failure - PP Deviation', marker=COLOR_FAILURE) %>% 
  add_segments(x="#02", xend="#22", y = THRESHOLD_MILD, yend = THRESHOLD_MILD, name="Threshold: Mild Change of PP",
                           line=list(color="blue", dash = 'dot')) %>%
  # add_segments(x="#02", xend="#22", y = THRESHOLD_EXTREME, yend = THRESHOLD_EXTREME, name="Threshold: Extreme Change of PP",
  #                          line=list(color="darkred", dash = 'dot')) %>%
  layout(yaxis = yAxis, barmode = 'group', title="Failure Driving \n Group=Cognitive")

htmltools::tagList(fig_Cognitive)
A marker object has been specified, but markers is not in the mode
Adding markers to the mode...
A marker object has been specified, but markers is not in the mode
Adding markers to the mode...
fig_Motoric <- plot_ly(combinedDf_Motoric, x = ~Subject, y = ~PP_Dev_2_Straight, type = 'bar', name = 'Cognitive - Mean PP (Straight)', marker=COLOR_COGNITIVE) %>%
  add_trace(y = ~PP_Dev_3_Straight, name = 'Motoric - Mean PP (Straight)', marker=COLOR_MOTORIC) %>% 
  add_trace(y = ~PP_Dev_2_Turning, name = 'Cognitive - Mean PP (Turning)', marker=COLOR_COGNITIVE) %>% 
  add_trace(y = ~PP_Dev_3_Turning, name = 'Motoric - Mean PP (Turning)', marker=COLOR_MOTORIC) %>% 
  add_trace(y = ~PP_Dev, name = 'Failure - PP Deviation', marker=COLOR_FAILURE) %>% 
  add_segments(x="#05", xend="#31", y = THRESHOLD_MILD, yend = THRESHOLD_MILD, name="Threshold: Mild Change of PP",
                           line=list(color="blue", dash = 'dot')) %>%
  # add_segments(x="#05", xend="#31", y = THRESHOLD_EXTREME, yend = THRESHOLD_EXTREME, name="Threshold: Extreme Change of PP",
  #                          line=list(color="darkred", dash = 'dot')) %>%
  layout(yaxis = yAxis, barmode = 'group', title="Failure Driving \n Group: Motoric")

htmltools::tagList(fig_Motoric)
A marker object has been specified, but markers is not in the mode
Adding markers to the mode...
A marker object has been specified, but markers is not in the mode
Adding markers to the mode...
library(nlme)

combinedDf$Subject = as.factor(combinedDf$Subject)
combinedDf$Activity = as.factor(combinedDf$Activity)

combinedDf$PP_Dev_Group = ifelse(combinedDf$PP_Dev > THRESHOLD_MILD, 1, 0)
model = lme(PP_Dev ~ 
              abs(PP_Dev_2_Straight)
              + abs(PP_Dev_3_Straight)
              + abs(PP_Dev_2_Turning) 
              + abs(PP_Dev_3_Turning)
              + factor(Activity), 
            random=~1|Subject,
            data=combinedDf,
            method="REML")

# anova(model)
summary(model)
Linear mixed-effects model fit by REML
 Data: combinedDf 

Random effects:
 Formula: ~1 | Subject
        (Intercept)   Residual
StdDev:  0.07501618 0.02813106

Fixed effects: PP_Dev ~ abs(PP_Dev_2_Straight) + abs(PP_Dev_3_Straight) + abs(PP_Dev_2_Turning) +      abs(PP_Dev_3_Turning) + factor(Activity) 
 Correlation: 
                       (Intr) a(PP_D_2_S a(PP_D_3_S a(PP_D_2_T a(PP_D_3_T fc(A)M
abs(PP_Dev_2_Straight)  0.598                                                   
abs(PP_Dev_3_Straight)  0.082  0.028                                            
abs(PP_Dev_2_Turning)  -0.508 -0.715     -0.483                                 
abs(PP_Dev_3_Turning)  -0.586 -0.456     -0.706      0.529                      
factor(Activity)M      -0.385 -0.171      0.355     -0.181     -0.125           
factor(Activity)NO     -0.154  0.026      0.547     -0.450     -0.368      0.616

Standardized Within-Group Residuals:
         Min           Q1          Med           Q3          Max 
-0.440076168 -0.154672364 -0.002413178  0.107752315  0.674410551 

Number of Observations: 21
Number of Groups: 21 
plot(model)

model = lme(PP_Dev ~ 
              abs(PP_Dev_2_Turning)
              + factor(Activity), 
            random=~1|Subject,
            data=combinedDf,
            method="REML")

# anova(model)
summary(model)
Linear mixed-effects model fit by REML
 Data: combinedDf 

Random effects:
 Formula: ~1 | Subject
        (Intercept) Residual
StdDev:  0.08150667 0.030565

Fixed effects: PP_Dev ~ abs(PP_Dev_2_Turning) + factor(Activity) 
 Correlation: 
                      (Intr) a(PP_D fc(A)M
abs(PP_Dev_2_Turning) -0.497              
factor(Activity)M     -0.457 -0.270       
factor(Activity)NO    -0.346 -0.423  0.550

Standardized Within-Group Residuals:
        Min          Q1         Med          Q3         Max 
-0.49096784 -0.21744976  0.01851302  0.20552883  0.50745083 

Number of Observations: 21
Number of Groups: 21 
plot(model)

model = lme(PP_Dev ~ 
              PP_Dev_2_Straight + 
              PP_Dev_3_Straight + 
              PP_Dev_1_Turning + 
              PP_Dev_2_Turning + 
              PP_Dev_3_Turning + 
              Std_PP_2 + 
              Std_PP_3 +
              factor(Activity), 
            random=~1|Subject,
            data=combinedDf,
            method="REML")

# anova(model)
summary(model)
Linear mixed-effects model fit by REML
 Data: combinedDf 

Random effects:
 Formula: ~1 | Subject
        (Intercept)   Residual
StdDev:  0.08634381 0.03237893

Fixed effects: PP_Dev ~ PP_Dev_2_Straight + PP_Dev_3_Straight + PP_Dev_1_Turning +      PP_Dev_2_Turning + PP_Dev_3_Turning + Std_PP_2 + Std_PP_3 +      factor(Activity) 
 Correlation: 
                   (Intr) PP_D_2_S PP_D_3_S PP_D_1 PP_D_2_T PP_D_3_T S_PP_2 S_PP_3 fc(A)M
PP_Dev_2_Straight  -0.056                                                                
PP_Dev_3_Straight   0.048 -0.363                                                         
PP_Dev_1_Turning   -0.797  0.130    0.176                                                
PP_Dev_2_Turning    0.360 -0.754    0.023   -0.422                                       
PP_Dev_3_Turning   -0.140  0.268   -0.700   -0.283 -0.252                                
Std_PP_2            0.199 -0.570   -0.066   -0.333  0.816   -0.134                       
Std_PP_3           -0.818  0.423   -0.201    0.672 -0.688    0.275   -0.604              
factor(Activity)M   0.162 -0.317    0.495   -0.054  0.166   -0.372    0.128 -0.430       
factor(Activity)NO -0.228 -0.225    0.426    0.191 -0.123   -0.235   -0.263  0.124  0.481

Standardized Within-Group Residuals:
        Min          Q1         Med          Q3         Max 
-0.48616985 -0.10946874 -0.02066106  0.16055277  0.56942657 

Number of Observations: 21
Number of Groups: 21 
plot(model)

combinedDf$PP_Dev <- NULL

combinedDf$Subject <- NULL
combinedDf$Activity_NO <- ifelse(combinedDf$Activity == "NO", 1, 0)
combinedDf$Activity_C <- ifelse(combinedDf$Activity == "C", 1, 0)
combinedDf$Activity_M <- ifelse(combinedDf$Activity == "M", 1, 0)
combinedDf$Activity <- NULL

combinedDf$Class <- ifelse(combinedDf$PP_Dev_Group == 1, T, F)
combinedDf$PP_Dev_Group <- NULL
# library(mefa)
# combinedDf <- rep(combinedDf, 10) 
# s=55, f=4

set.seed(5151) 
n_folds <- 3
params <- param <- list(objective       = "binary:logistic", 
               booster          = "gbtree",
               eval_metric      = "auc",
               eta              = 0.1,
               max_depth        = 8,
               alpha            = 1,
               lambda           = 0,
               gamma            = 0.3,
               min_child_weight = 0.3,
               subsample        = 1,
               colsample_bytree = 0.5)
           
# xgb_m <- xgb.cv(   params               = param,
#                   data = as.matrix(combinedDf %>% select(-Class)) ,
#                   label =  combinedDf$Class,
#                   nrounds             = 100,
#                   verbose             = F,
#                   prediction          = T,
#                   maximize            = T,
#                   nfold = n_folds,
#                   metrics  = "auc",
#                   early_stopping_rounds = 100,
#                   stratified       = F,
#                   scale_pos_weight = 0.5)
# 
# # xgb_m$evaluation_log[xgb_m$best_iteration,"test_auc_mean"]
# xgb_m$evaluation_log[xgb_m$best_iteration,]

# Error         
xgb_m <- xgb.cv(   params               = param,
                  data = as.matrix(combinedDf %>% select(-Class)) ,
                  label =  combinedDf$Class,
                  nrounds             = 500,
                  verbose             = F,
                  prediction          = T,
                  maximize            = T,
                  nfold               = n_folds,
                  metrics             = c("auc", "error"),
                  early_stopping_rounds = 100,
                  stratified            = F,
                  scale_pos_weight      = 3.05)

# xgb_m$evaluation_log[xgb_m$best_iteration,"test_auc_mean"]
xgb_m$evaluation_log[xgb_m$best_iteration,]
NA
library(pROC)

# it = which.max(xgb_m$evaluation_log$test_auc_mean)
# best.iter = xgb_m$evaluation_log$iter[it]
# best.iter 

plot(pROC::roc(response = ifelse(combinedDf$Class==T, 1, 0),
               predictor = xgb_m$pred,
               levels=c(0, 1)),
     lwd=1.5) 
Setting direction: controls < cases

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmlmKCFyZXF1aXJlKCJwbG90bHkiKSkge2luc3RhbGwucGFja2FnZXMoInBsb3RseSIpfQoKIyBpbnN0YWxsLnBhY2thZ2VzKCJsYXRleDJleHAiKQojIGluc3RhbGwucGFja2FnZXMoIkJpb2NNYW5hZ2VyIikgCiMgaW5zdGFsbC5wYWNrYWdlcygiY29ycnBsb3QiKQojIEJpb2NNYW5hZ2VyOjppbnN0YWxsKCJFQkltYWdlIikKCmlmKCFyZXF1aXJlKCJsbWU0Iikpe2luc3RhbGwucGFja2FnZXMoImxtZTQiKX0KaWYoIXJlcXVpcmUoImxtZXJUZXN0Iikpe2luc3RhbGwucGFja2FnZXMoImxtZXJUZXN0Iil9CmlmKCFyZXF1aXJlKCJubG1lIikpe2luc3RhbGwucGFja2FnZXMoIm5sbWUiKX0KaWYoIXJlcXVpcmUoImZvcm1hdHRhYmxlIikpe2luc3RhbGwucGFja2FnZXMoImZvcm1hdHRhYmxlIil9CmlmKCFyZXF1aXJlKCJ4Z2Jvb3N0Iikpe2luc3RhbGwucGFja2FnZXMoInhnYm9vc3QiKX0KaWYoIXJlcXVpcmUoInByb2Nlc3N4IikpIHtpbnN0YWxsLnBhY2thZ2VzKCJwcm9jZXNzeCIpfQoKaWYoIXJlcXVpcmUoIm1lZmEiKSl7aW5zdGFsbC5wYWNrYWdlcygibWVmYSIpfQoKbGlicmFyeShwbG90bHkpCmxpYnJhcnkobG1lNCkKbGlicmFyeShsbWVyVGVzdCkKbGlicmFyeShubG1lKQpsaWJyYXJ5KGZvcm1hdHRhYmxlKQpsaWJyYXJ5KHhnYm9vc3QpCgojIyMgTG9hZCBsaWJyYXJpZXMKbGlicmFyeShFQkltYWdlKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoc3RyaW5ncikKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkobGF0ZXgyZXhwKQpwYWNrYWdlVmVyc2lvbigncGxvdGx5JykKU3lzLnNldGVudigicGxvdGx5X3VzZXJuYW1lIj0idGh1eW5oMzIiKQpTeXMuc2V0ZW52KCJwbG90bHlfYXBpX2tleSI9InhjU3YxeXp1akRjMUlHRXdRbHIyIikKCmBgYAoKYGBge3J9CmRyaXZlMSA8LSByZWFkLmNzdignLi4vLi4vLi4vZGF0YS9UVDEvcHJlcHJvY2Vzc2VkL0FuYWx5c2lzL1RUMV9Ecml2ZV8xX1BQLmNzdicpCmRyaXZlMiA8LSByZWFkLmNzdignLi4vLi4vLi4vZGF0YS9UVDEvcHJlcHJvY2Vzc2VkL0FuYWx5c2lzL1RUMV9Ecml2ZV8yX1BQLmNzdicpCmRyaXZlMyA8LSByZWFkLmNzdignLi4vLi4vLi4vZGF0YS9UVDEvcHJlcHJvY2Vzc2VkL0FuYWx5c2lzL1RUMV9Ecml2ZV8zX1BQLmNzdicpCmRyaXZlNCA8LSByZWFkLmNzdignLi4vLi4vLi4vZGF0YS9UVDEvcHJlcHJvY2Vzc2VkL0FuYWx5c2lzL1RUMV9Ecml2ZV80X1BQLmNzdicsIHN0cmluZ3NBc0ZhY3RvcnMgPSBUKQpgYGAKCmBgYHtyfQpjb21iaW5lZERmIDwtIGNiaW5kKGRyaXZlNCwgCiAgICAgICAgICAgICAgICAgICAgZHJpdmUxJE1lYW5QUF9TZWcwLCAKICAgICAgICAgICAgICAgICAgICBkcml2ZTIkTWVhblBQX1NlZ01heCwgZHJpdmUzJE1lYW5QUF9TZWdNYXgsIAogICAgICAgICAgICAgICAgICAgIGRyaXZlMiRNZWFuUFBfU2VnMCwgZHJpdmUzJE1lYW5QUF9TZWcwLAogICAgICAgICAgICAgICAgICAgIGRyaXZlMiRTdGRQUCwgZHJpdmUzJFN0ZFBQIAogICAgICAgICAgICAgICAgICApCm5hbWVzKGNvbWJpbmVkRGYpIDwtIGMobmFtZXMoZHJpdmU0KSwgCiAgICAgICAgICAgICAgICAgICAgICAgIlBQX0Rldl8xX1R1cm5pbmciLAogICAgICAgICAgICAgICAgICAgICAgICJQUF9EZXZfMl9TdHJhaWdodCIsICJQUF9EZXZfM19TdHJhaWdodCIsIAogICAgICAgICAgICAgICAgICAgICAgICJQUF9EZXZfMl9UdXJuaW5nIiwgIlBQX0Rldl8zX1R1cm5pbmciLCAKICAgICAgICAgICAgICAgICAgICAgICAiU3RkX1BQXzIiLCAiU3RkX1BQXzMiKQoKY29tYmluZWREZiRTdWJqZWN0IDwtIHBhc3RlMCgiIyIsIHN0cl9wYWQoY29tYmluZWREZiRTdWJqZWN0LCAyLCBwYWQ9IjAiKSkKYGBgCgpgYGB7cn0KY29tYmluZWREZl9Ob1N0cmVzc29yIDwtIGNvbWJpbmVkRGZbY29tYmluZWREZiRBY3Rpdml0eSA9PSAiTk8iLF0KY29tYmluZWREZl9Db2duaXRpdmUgPC0gY29tYmluZWREZltjb21iaW5lZERmJEFjdGl2aXR5ID09ICJDIixdCmNvbWJpbmVkRGZfTW90b3JpYyA8LSBjb21iaW5lZERmW2NvbWJpbmVkRGYkQWN0aXZpdHkgPT0gIk0iLF0KCmNvbWJpbmVkRGZfTm9TdHJlc3NvciRTdWJqZWN0IDwtIGFzLmZhY3Rvcihjb21iaW5lZERmX05vU3RyZXNzb3IkU3ViamVjdCkKY29tYmluZWREZl9Db2duaXRpdmUkU3ViamVjdCA8LSBhcy5mYWN0b3IoY29tYmluZWREZl9Db2duaXRpdmUkU3ViamVjdCkKY29tYmluZWREZl9Nb3RvcmljJFN1YmplY3QgPC0gYXMuZmFjdG9yKGNvbWJpbmVkRGZfTW90b3JpYyRTdWJqZWN0KQpgYGAKCmBgYHtyfQpDT0xPUl9OT1JNQUwgPC0gbGlzdChjb2xvcj0ncmdiKDEyMCwxMjAsMTIwKScpCkNPTE9SX0NPR05JVElWRSA8LSBsaXN0KGNvbG9yPSdyZ2IoMTU4LDIwMiwyMjUpJykKQ09MT1JfTU9UT1JJQyA8LSBsaXN0KGNvbG9yPSdyZ2IoNTgsMjAwLDIyNSknKQpDT0xPUl9GQUlMVVJFIDwtIGxpc3QoY29sb3I9J3JlZCcpCgp5QXhpcyA8LSBsaXN0KAogIHRpdGxlID0gJ1BlcmluYXNhbCBQZXJzcGlyYXRpb24gKExvZyknLAogIHJhbmdlPWMoLTAuMywgMC41KQopCgpUSFJFU0hPTERfTUlMRCA9IDAuMDcKVEhSRVNIT0xEX0VYVFJFTUUgPSAwLjIKCk1BUktFUl9MSU5FX01JTEQgPSBsaXN0KGNvbG9yPSJibHVlIikKTUFSS0VSX0xJTkVfRVhUUkVNRSA9IGxpc3QoY29sb3I9InJlZCIpCmBgYAoKYGBge3IsIHdhcm5pbmc9Rn0KZmlnX05vU3RyZXNzb3IgPC0gcGxvdF9seShjb21iaW5lZERmX05vU3RyZXNzb3IsIHggPSB+U3ViamVjdCwgeSA9IH5QUF9EZXZfMl9TdHJhaWdodCwgdHlwZSA9ICdiYXInLCBuYW1lID0gJ0NvZ25pdGl2ZSAtIE1lYW4gUFAgKFN0cmFpZ2h0KScsIG1hcmtlcj1DT0xPUl9DT0dOSVRJVkUpICU+JQogIGFkZF90cmFjZSh5ID0gflBQX0Rldl8zX1N0cmFpZ2h0LCBuYW1lID0gJ01vdG9yaWMgLSBNZWFuIFBQIChTdHJhaWdodCknLCBtYXJrZXI9Q09MT1JfTU9UT1JJQykgJT4lIAogIGFkZF90cmFjZSh5ID0gflBQX0Rldl8yX1R1cm5pbmcsIG5hbWUgPSAnQ29nbml0aXZlIC0gTWVhbiBQUCAoVHVybmluZyknLCBtYXJrZXI9Q09MT1JfQ09HTklUSVZFKSAlPiUgCiAgYWRkX3RyYWNlKHkgPSB+UFBfRGV2XzNfVHVybmluZywgbmFtZSA9ICdNb3RvcmljIC0gTWVhbiBQUCAoVHVybmluZyknLCBtYXJrZXI9Q09MT1JfTU9UT1JJQykgJT4lIAogIGFkZF90cmFjZSh5ID0gflBQX0RldiwgbmFtZSA9ICdGYWlsdXJlIC0gUFAgRGV2aWF0aW9uJywgbWFya2VyPUNPTE9SX0ZBSUxVUkUpICU+JSAKICBhZGRfc2VnbWVudHMoeD0iIzAxIiwgeGVuZD0iIzQxIiwgeSA9IFRIUkVTSE9MRF9NSUxELCB5ZW5kID0gVEhSRVNIT0xEX01JTEQsIG5hbWU9IlRocmVzaG9sZDogTWlsZCBDaGFuZ2Ugb2YgUFAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoID0gJ2RvdCcpKSAlPiUKICAjIGFkZF9zZWdtZW50cyh4PSIjMDEiLCB4ZW5kPSIjNDEiLCB5ID0gVEhSRVNIT0xEX0VYVFJFTUUsIHllbmQgPSBUSFJFU0hPTERfRVhUUkVNRSwgbmFtZT0iVGhyZXNob2xkOiBFeHRyZW1lIENoYW5nZSBvZiBQUCIsCiAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJkYXJrcmVkIiwgZGFzaCA9ICdkb3QnKSkgJT4lCiAgbGF5b3V0KHlheGlzID0geUF4aXMsIGJhcm1vZGUgPSAnZ3JvdXAnLCB0aXRsZT0iRmFpbHVyZSBEcml2aW5nIFxuIEdyb3VwPU5vIFN0cmVzc29yIikKCmh0bWx0b29sczo6dGFnTGlzdChmaWdfTm9TdHJlc3NvcikKYGBgCgpgYGB7ciwgd2FybmluZz1GfQpmaWdfQ29nbml0aXZlIDwtIHBsb3RfbHkoY29tYmluZWREZl9Db2duaXRpdmUsIHggPSB+U3ViamVjdCwgeSA9IH5QUF9EZXZfMl9TdHJhaWdodCwgdHlwZSA9ICdiYXInLCBuYW1lID0gJ0NvZ25pdGl2ZSAtIE1lYW4gUFAgKFN0cmFpZ2h0KScsIG1hcmtlcj1DT0xPUl9DT0dOSVRJVkUpICU+JQogIGFkZF90cmFjZSh5ID0gflBQX0Rldl8zX1N0cmFpZ2h0LCBuYW1lID0gJ01vdG9yaWMgLSBNZWFuIFBQIChTdHJhaWdodCknLCBtYXJrZXI9Q09MT1JfTU9UT1JJQykgJT4lIAogIGFkZF90cmFjZSh5ID0gflBQX0Rldl8yX1R1cm5pbmcsIG5hbWUgPSAnQ29nbml0aXZlIC0gTWVhbiBQUCAoVHVybmluZyknLCBtYXJrZXI9Q09MT1JfQ09HTklUSVZFKSAlPiUgCiAgYWRkX3RyYWNlKHkgPSB+UFBfRGV2XzNfVHVybmluZywgbmFtZSA9ICdNb3RvcmljIC0gTWVhbiBQUCAoVHVybmluZyknLCBtYXJrZXI9Q09MT1JfTU9UT1JJQykgJT4lIAogIGFkZF90cmFjZSh5ID0gflBQX0RldiwgbmFtZSA9ICdGYWlsdXJlIC0gUFAgRGV2aWF0aW9uJywgbWFya2VyPUNPTE9SX0ZBSUxVUkUpICU+JSAKICBhZGRfc2VnbWVudHMoeD0iIzAyIiwgeGVuZD0iIzIyIiwgeSA9IFRIUkVTSE9MRF9NSUxELCB5ZW5kID0gVEhSRVNIT0xEX01JTEQsIG5hbWU9IlRocmVzaG9sZDogTWlsZCBDaGFuZ2Ugb2YgUFAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lPWxpc3QoY29sb3I9ImJsdWUiLCBkYXNoID0gJ2RvdCcpKSAlPiUKICAjIGFkZF9zZWdtZW50cyh4PSIjMDIiLCB4ZW5kPSIjMjIiLCB5ID0gVEhSRVNIT0xEX0VYVFJFTUUsIHllbmQgPSBUSFJFU0hPTERfRVhUUkVNRSwgbmFtZT0iVGhyZXNob2xkOiBFeHRyZW1lIENoYW5nZSBvZiBQUCIsCiAgIyAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJkYXJrcmVkIiwgZGFzaCA9ICdkb3QnKSkgJT4lCiAgbGF5b3V0KHlheGlzID0geUF4aXMsIGJhcm1vZGUgPSAnZ3JvdXAnLCB0aXRsZT0iRmFpbHVyZSBEcml2aW5nIFxuIEdyb3VwPUNvZ25pdGl2ZSIpCgpodG1sdG9vbHM6OnRhZ0xpc3QoZmlnX0NvZ25pdGl2ZSkKYGBgCgoKCmBgYHtyLCB3YXJuaW5nPUZ9CmZpZ19Nb3RvcmljIDwtIHBsb3RfbHkoY29tYmluZWREZl9Nb3RvcmljLCB4ID0gflN1YmplY3QsIHkgPSB+UFBfRGV2XzJfU3RyYWlnaHQsIHR5cGUgPSAnYmFyJywgbmFtZSA9ICdDb2duaXRpdmUgLSBNZWFuIFBQIChTdHJhaWdodCknLCBtYXJrZXI9Q09MT1JfQ09HTklUSVZFKSAlPiUKICBhZGRfdHJhY2UoeSA9IH5QUF9EZXZfM19TdHJhaWdodCwgbmFtZSA9ICdNb3RvcmljIC0gTWVhbiBQUCAoU3RyYWlnaHQpJywgbWFya2VyPUNPTE9SX01PVE9SSUMpICU+JSAKICBhZGRfdHJhY2UoeSA9IH5QUF9EZXZfMl9UdXJuaW5nLCBuYW1lID0gJ0NvZ25pdGl2ZSAtIE1lYW4gUFAgKFR1cm5pbmcpJywgbWFya2VyPUNPTE9SX0NPR05JVElWRSkgJT4lIAogIGFkZF90cmFjZSh5ID0gflBQX0Rldl8zX1R1cm5pbmcsIG5hbWUgPSAnTW90b3JpYyAtIE1lYW4gUFAgKFR1cm5pbmcpJywgbWFya2VyPUNPTE9SX01PVE9SSUMpICU+JSAKICBhZGRfdHJhY2UoeSA9IH5QUF9EZXYsIG5hbWUgPSAnRmFpbHVyZSAtIFBQIERldmlhdGlvbicsIG1hcmtlcj1DT0xPUl9GQUlMVVJFKSAlPiUgCiAgYWRkX3NlZ21lbnRzKHg9IiMwNSIsIHhlbmQ9IiMzMSIsIHkgPSBUSFJFU0hPTERfTUlMRCwgeWVuZCA9IFRIUkVTSE9MRF9NSUxELCBuYW1lPSJUaHJlc2hvbGQ6IE1pbGQgQ2hhbmdlIG9mIFBQIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZT1saXN0KGNvbG9yPSJibHVlIiwgZGFzaCA9ICdkb3QnKSkgJT4lCiAgIyBhZGRfc2VnbWVudHMoeD0iIzA1IiwgeGVuZD0iIzMxIiwgeSA9IFRIUkVTSE9MRF9FWFRSRU1FLCB5ZW5kID0gVEhSRVNIT0xEX0VYVFJFTUUsIG5hbWU9IlRocmVzaG9sZDogRXh0cmVtZSBDaGFuZ2Ugb2YgUFAiLAogICMgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmU9bGlzdChjb2xvcj0iZGFya3JlZCIsIGRhc2ggPSAnZG90JykpICU+JQogIGxheW91dCh5YXhpcyA9IHlBeGlzLCBiYXJtb2RlID0gJ2dyb3VwJywgdGl0bGU9IkZhaWx1cmUgRHJpdmluZyBcbiBHcm91cDogTW90b3JpYyIpCgpodG1sdG9vbHM6OnRhZ0xpc3QoZmlnX01vdG9yaWMpCmBgYAoKCmBgYHtyfQpsaWJyYXJ5KG5sbWUpCgpjb21iaW5lZERmJFN1YmplY3QgPSBhcy5mYWN0b3IoY29tYmluZWREZiRTdWJqZWN0KQpjb21iaW5lZERmJEFjdGl2aXR5ID0gYXMuZmFjdG9yKGNvbWJpbmVkRGYkQWN0aXZpdHkpCgpjb21iaW5lZERmJFBQX0Rldl9Hcm91cCA9IGlmZWxzZShjb21iaW5lZERmJFBQX0RldiA+IFRIUkVTSE9MRF9NSUxELCAxLCAwKQpgYGAKCmBgYHtyfQptb2RlbCA9IGxtZShQUF9EZXYgfiAKICAgICAgICAgICAgICBhYnMoUFBfRGV2XzJfU3RyYWlnaHQpCiAgICAgICAgICAgICAgKyBhYnMoUFBfRGV2XzNfU3RyYWlnaHQpCiAgICAgICAgICAgICAgKyBhYnMoUFBfRGV2XzJfVHVybmluZykgCiAgICAgICAgICAgICAgKyBhYnMoUFBfRGV2XzNfVHVybmluZykKICAgICAgICAgICAgICArIGZhY3RvcihBY3Rpdml0eSksIAogICAgICAgICAgICByYW5kb209fjF8U3ViamVjdCwKICAgICAgICAgICAgZGF0YT1jb21iaW5lZERmLAogICAgICAgICAgICBtZXRob2Q9IlJFTUwiKQoKIyBhbm92YShtb2RlbCkKc3VtbWFyeShtb2RlbCkKcGxvdChtb2RlbCkKYGBgCgpgYGB7cn0KbW9kZWwgPSBsbWUoUFBfRGV2IH4gCiAgICAgICAgICAgICAgYWJzKFBQX0Rldl8yX1R1cm5pbmcpCiAgICAgICAgICAgICAgKyBmYWN0b3IoQWN0aXZpdHkpLCAKICAgICAgICAgICAgcmFuZG9tPX4xfFN1YmplY3QsCiAgICAgICAgICAgIGRhdGE9Y29tYmluZWREZiwKICAgICAgICAgICAgbWV0aG9kPSJSRU1MIikKCiMgYW5vdmEobW9kZWwpCnN1bW1hcnkobW9kZWwpCnBsb3QobW9kZWwpCmBgYAoKYGBge3J9Cm1vZGVsID0gbG1lKFBQX0RldiB+IAogICAgICAgICAgICAgIFBQX0Rldl8yX1N0cmFpZ2h0ICsgCiAgICAgICAgICAgICAgUFBfRGV2XzNfU3RyYWlnaHQgKyAKICAgICAgICAgICAgICBQUF9EZXZfMV9UdXJuaW5nICsgCiAgICAgICAgICAgICAgUFBfRGV2XzJfVHVybmluZyArIAogICAgICAgICAgICAgIFBQX0Rldl8zX1R1cm5pbmcgKyAKICAgICAgICAgICAgICBTdGRfUFBfMiArIAogICAgICAgICAgICAgIFN0ZF9QUF8zICsKICAgICAgICAgICAgICBmYWN0b3IoQWN0aXZpdHkpLCAKICAgICAgICAgICAgcmFuZG9tPX4xfFN1YmplY3QsCiAgICAgICAgICAgIGRhdGE9Y29tYmluZWREZiwKICAgICAgICAgICAgbWV0aG9kPSJSRU1MIikKCiMgYW5vdmEobW9kZWwpCnN1bW1hcnkobW9kZWwpCnBsb3QobW9kZWwpCmBgYAoKYGBge3J9CmNvbWJpbmVkRGYkUFBfRGV2IDwtIE5VTEwKCmNvbWJpbmVkRGYkU3ViamVjdCA8LSBOVUxMCmNvbWJpbmVkRGYkQWN0aXZpdHlfTk8gPC0gaWZlbHNlKGNvbWJpbmVkRGYkQWN0aXZpdHkgPT0gIk5PIiwgMSwgMCkKY29tYmluZWREZiRBY3Rpdml0eV9DIDwtIGlmZWxzZShjb21iaW5lZERmJEFjdGl2aXR5ID09ICJDIiwgMSwgMCkKY29tYmluZWREZiRBY3Rpdml0eV9NIDwtIGlmZWxzZShjb21iaW5lZERmJEFjdGl2aXR5ID09ICJNIiwgMSwgMCkKY29tYmluZWREZiRBY3Rpdml0eSA8LSBOVUxMCgpjb21iaW5lZERmJENsYXNzIDwtIGlmZWxzZShjb21iaW5lZERmJFBQX0Rldl9Hcm91cCA9PSAxLCBULCBGKQpjb21iaW5lZERmJFBQX0Rldl9Hcm91cCA8LSBOVUxMCmBgYAoKYGBge3J9CiMgbGlicmFyeShtZWZhKQojIGNvbWJpbmVkRGYgPC0gcmVwKGNvbWJpbmVkRGYsIDEwKSAKYGBgCgpgYGB7cn0KIyBzPTU1LCBmPTQKCnNldC5zZWVkKDUxNTEpIApuX2ZvbGRzIDwtIDMKcGFyYW1zIDwtIHBhcmFtIDwtIGxpc3Qob2JqZWN0aXZlICAgICAgID0gImJpbmFyeTpsb2dpc3RpYyIsIAogICAgICAgICAgICAgICBib29zdGVyICAgICAgICAgID0gImdidHJlZSIsCiAgICAgICAgICAgICAgIGV2YWxfbWV0cmljICAgICAgPSAiYXVjIiwKICAgICAgICAgICAgICAgZXRhICAgICAgICAgICAgICA9IDAuMSwKICAgICAgICAgICAgICAgbWF4X2RlcHRoICAgICAgICA9IDgsCiAgICAgICAgICAgICAgIGFscGhhICAgICAgICAgICAgPSAxLAogICAgICAgICAgICAgICBsYW1iZGEgICAgICAgICAgID0gMCwKICAgICAgICAgICAgICAgZ2FtbWEgICAgICAgICAgICA9IDAuMywKICAgICAgICAgICAgICAgbWluX2NoaWxkX3dlaWdodCA9IDAuMywKICAgICAgICAgICAgICAgc3Vic2FtcGxlICAgICAgICA9IDEsCiAgICAgICAgICAgICAgIGNvbHNhbXBsZV9ieXRyZWUgPSAwLjUpCiAgICAgICAgICAgCiMgeGdiX20gPC0geGdiLmN2KCAgIHBhcmFtcyAgICAgICAgICAgICAgID0gcGFyYW0sCiMgICAgICAgICAgICAgICAgICAgZGF0YSA9IGFzLm1hdHJpeChjb21iaW5lZERmICU+JSBzZWxlY3QoLUNsYXNzKSkgLAojICAgICAgICAgICAgICAgICAgIGxhYmVsID0gIGNvbWJpbmVkRGYkQ2xhc3MsCiMgICAgICAgICAgICAgICAgICAgbnJvdW5kcyAgICAgICAgICAgICA9IDEwMCwKIyAgICAgICAgICAgICAgICAgICB2ZXJib3NlICAgICAgICAgICAgID0gRiwKIyAgICAgICAgICAgICAgICAgICBwcmVkaWN0aW9uICAgICAgICAgID0gVCwKIyAgICAgICAgICAgICAgICAgICBtYXhpbWl6ZSAgICAgICAgICAgID0gVCwKIyAgICAgICAgICAgICAgICAgICBuZm9sZCA9IG5fZm9sZHMsCiMgICAgICAgICAgICAgICAgICAgbWV0cmljcyAgPSAiYXVjIiwKIyAgICAgICAgICAgICAgICAgICBlYXJseV9zdG9wcGluZ19yb3VuZHMgPSAxMDAsCiMgICAgICAgICAgICAgICAgICAgc3RyYXRpZmllZCAgICAgICA9IEYsCiMgICAgICAgICAgICAgICAgICAgc2NhbGVfcG9zX3dlaWdodCA9IDAuNSkKIyAKIyAjIHhnYl9tJGV2YWx1YXRpb25fbG9nW3hnYl9tJGJlc3RfaXRlcmF0aW9uLCJ0ZXN0X2F1Y19tZWFuIl0KIyB4Z2JfbSRldmFsdWF0aW9uX2xvZ1t4Z2JfbSRiZXN0X2l0ZXJhdGlvbixdCgojIEVycm9yICAgICAgICAgCnhnYl9tIDwtIHhnYi5jdiggICBwYXJhbXMgICAgICAgICAgICAgICA9IHBhcmFtLAogICAgICAgICAgICAgICAgICBkYXRhID0gYXMubWF0cml4KGNvbWJpbmVkRGYgJT4lIHNlbGVjdCgtQ2xhc3MpKSAsCiAgICAgICAgICAgICAgICAgIGxhYmVsID0gIGNvbWJpbmVkRGYkQ2xhc3MsCiAgICAgICAgICAgICAgICAgIG5yb3VuZHMgICAgICAgICAgICAgPSA1MDAsCiAgICAgICAgICAgICAgICAgIHZlcmJvc2UgICAgICAgICAgICAgPSBGLAogICAgICAgICAgICAgICAgICBwcmVkaWN0aW9uICAgICAgICAgID0gVCwKICAgICAgICAgICAgICAgICAgbWF4aW1pemUgICAgICAgICAgICA9IFQsCiAgICAgICAgICAgICAgICAgIG5mb2xkICAgICAgICAgICAgICAgPSBuX2ZvbGRzLAogICAgICAgICAgICAgICAgICBtZXRyaWNzICAgICAgICAgICAgID0gYygiYXVjIiwgImVycm9yIiksCiAgICAgICAgICAgICAgICAgIGVhcmx5X3N0b3BwaW5nX3JvdW5kcyA9IDEwMCwKICAgICAgICAgICAgICAgICAgc3RyYXRpZmllZCAgICAgICAgICAgID0gRiwKICAgICAgICAgICAgICAgICAgc2NhbGVfcG9zX3dlaWdodCAgICAgID0gMy4wNSkKCiMgeGdiX20kZXZhbHVhdGlvbl9sb2dbeGdiX20kYmVzdF9pdGVyYXRpb24sInRlc3RfYXVjX21lYW4iXQp4Z2JfbSRldmFsdWF0aW9uX2xvZ1t4Z2JfbSRiZXN0X2l0ZXJhdGlvbixdCgpgYGAKCmBgYHtyfQpsaWJyYXJ5KHBST0MpCgojIGl0ID0gd2hpY2gubWF4KHhnYl9tJGV2YWx1YXRpb25fbG9nJHRlc3RfYXVjX21lYW4pCiMgYmVzdC5pdGVyID0geGdiX20kZXZhbHVhdGlvbl9sb2ckaXRlcltpdF0KIyBiZXN0Lml0ZXIgCgpwbG90KHBST0M6OnJvYyhyZXNwb25zZSA9IGlmZWxzZShjb21iaW5lZERmJENsYXNzPT1ULCAxLCAwKSwKICAgICAgICAgICAgICAgcHJlZGljdG9yID0geGdiX20kcHJlZCwKICAgICAgICAgICAgICAgbGV2ZWxzPWMoMCwgMSkpLAogICAgIGx3ZD0xLjUpIApgYGAKCgoK